package cfsmon.common;

import java.util.LinkedList;
import java.util.List;

/**
 * An event has a name and a list of formal parameters.
 * @author Alexander Gebhardt
 *
 */
public class Event implements Comparable<Event>{

	/**
	 * The runningID is used as a static counter when events
	 * are instantiated by a specification parser. The counter
	 * ensures that all events are assigned different ids.
	 */
	private static int runningID = 0;
	/**
	 * The event id is used by the monitoring-code generator
	 * instead of the event name to generate more efficient
	 * monitoring code. 
	 */
	private int id;
	/**
	 * The name of the event as given in a specification file
	 */
	public final String name;
	/**
	 * The list of formal parameters associated with this event.
	 */
	public final List<Parameter> parameters;
	
	/**
	 * This constructor instantiates an event.
	 * If a name is supplied, the name will be stored,
	 * otherwise an automatically generated name will be used. 
	 * @param name The name of the event
	 */
	public Event(String name){
		super();
		if (name == null){
			this.name = "e" + runningID;
		} else{
			this.name = name;
		}
		this.id = runningID;
		runningID++;
		this.parameters = new LinkedList<Parameter>();
	}
	
	/**
	 * Returns a function-declaration-style string representation
	 * of this event including its parameter list.
	 */
	public String toString(){
		return name + parameters.toString();
	}
	
	/**
	 * Returns the internally assigned ID of this event.
	 */
	public int getID(){
		return id;
	}

	/**
	 * Two events are compared in three steps:
	 * 1) by their names
	 * 2) by the contents of their parameter lists
	 * 3) by the size of their parameter lists
	 */
	@Override
	public int compareTo(Event arg0) {
		int tmp = this.name.compareTo(arg0.name);
		if (tmp != 0){
			return tmp;			
		} else{
			if (this.parameters.containsAll(arg0.parameters) &&
					arg0.parameters.containsAll(this.parameters)){
				return 0;
			} else {
				if (this.parameters.size() <= arg0.parameters.size()){
					return -1;
				} else {
					return 1;
				}
			}
		}
	}
	
}
